現在我的工作流裡有五十幾個 skill。有人問我怎麼寫出來的,我說:第一個是從別人開源的版本開始改的。
那是一個除錯用的 investigate skill,核心只有一句話:沒有找到根本原因(root cause)之前,禁止修 code。 我先照著用,再加入 iOS 常見問題的對照表,例如資料競爭、主執行緒使用錯誤和循環參照,讓它更適合我的工作。
後來,我才把不同的 skill 串成一條工作流,由一個入口引導 AI 走完開發階段。
回頭看,這個過程分成三步:先用現成的 → 改成適合自己的 → 串成工作流。 今天先看懂一份 skill 的結構,再把專案裡的一段操作流程寫成自己的版本。
Day 3 用 CLAUDE.md 記錄專案規則,Day 4 補齊執行任務需要的情境。接下來,如果某件事會反覆做,就可以把它整理成 Skill。
Skill 的核心是一份 Markdown,寫清楚「遇到什麼情況,按照哪些步驟做」。 你可以把它想成給新同事的 SOP 手冊,只是讀者換成 AI。
在這個系列的用法裡,CLAUDE.md 放每次工作都需要知道的規則;Skill 則放特定任務的操作細節,使用時才讀取。比如「不要覆蓋測試資料」是專案規則,「更新快照時要下載哪些檔案、執行哪個腳本、怎麼驗證」就是一份 SOP。
把流程寫下來,不能保證 AI 每次都做對,但能讓你有明確的檢查依據:它漏了哪一步?在哪裡應該停下來?輸出是否足以讓人驗收?
一份 skill 可以只有 SKILL.md;需要更多資料時,再加參考文件和腳本:
my-skill/
├── SKILL.md ← 使用時機與操作步驟
├── references/ ← 詳細規範、模板(選填)
└── scripts/ ← 輔助腳本(選填)
SKILL.md 分成兩部分。
第一部分是檔案開頭的設定區塊(frontmatter),說明它叫什麼、何時使用。
---
name: refresh-snapshot
description: >
做什麼,以及何時使用。附上使用者可能說的話,必要時補充不適用的情況。
---
description 要讓 AI 能判斷這份 skill 是否適合目前的任務。只寫「更新資料」太模糊;寫成「當使用者說『更新快照』『刷新排班資料』『活動前更新內建資料』時使用」,就比較容易對應到實際需求。
第二部分是正文(body),交代啟用後怎麼做。 第一份可以先寫五段:
重點是把容易漏掉的判斷寫清楚,不必一開始就做出很厚的手冊。
第一份 skill 可以從專案裡已經在手動執行的流程開始。
IMS 的 README 有一段「更新內建資料快照」:活動前下載遠端的 schedule.js、corrections.js,更新 IMS/Resources/,再產生 Widget 使用的 snapshot.bundle.json。
流程不長,但有幾個容易漏掉的地方:只更新 App 資料,忘了重新產生 Widget 快照;更新後沒跑測試;或把測試用的 Fixtures/ 也一起覆蓋,讓測試開始依賴實際的人名與排班。
把這些提醒放回步驟裡,就得到下面這份 skill。範例預計放在 .claude/skills/refresh-snapshot/SKILL.md;使用前,要先把下載位置、產生腳本和測試指令確認好。
---
name: refresh-snapshot
description: >
更新 IMS 內建的離線資料快照。當使用者說「更新快照」「刷新排班資料」
「更新 bundle」「活動前更新內建資料」時使用。
更新 App 資料、重新產生 Widget 快照,並執行測試。
不覆蓋 IMSTests/Fixtures,該目錄是測試用資料。
---
# refresh-snapshot
將遠端排班資料更新為 App 與 Widget 的內建離線備援資料。
## 何時用
- 活動前需要更新內建快照。
- 遠端人名或任務已變更,需要同步離線資料。
## 何時不用
- 只是檢查遠端資料有沒有變動。
- 需要調整測試用的 Fixtures;這是另一個任務。
## 步驟
1. 檢查 `git status`。若有尚未處理的修改,先停下來請使用者確認。
2. 從專案記錄的資料來源下載兩個檔案,更新
`IMS/Resources/schedule.bundle.js` 和 `IMS/Resources/corrections.bundle.js`。
3. 提供 `git diff --stat`,並摘要人員數、任務數與內容的變更。
4. 執行 `scripts/gen-snapshot.swift`,重新產生
`IMSWidget/Resources/snapshot.bundle.json`。
若腳本不存在或執行失敗,停下來回報,不要手改 JSON。
5. 執行 CLAUDE.md 記錄的完整測試指令,保留輸出。
測試失敗時停下來回報,不要為了通過而放寬測試。
6. 列出變更檔案與驗證結果,不自行 commit,交由使用者檢查。
## 常見錯誤
- 覆蓋 `IMSTests/Fixtures/`,讓測試依賴實際排班。
- 腳本失敗後直接手改 JSON,導致下次無法重現產生流程。
- 只說「更新完成」,沒有提供資料差異和測試結果。
- 未經使用者檢查就 commit 資料更新。
## 產出
變更檔案清單、資料差異摘要、測試輸出,以及尚未解決的問題。
寫完後,開一個新對話說「幫我更新快照」,觀察 AI 是否按順序檢查、更新、產生快照與驗證,最後交出結果讓你檢查。如果它漏了步驟,回頭確認該步驟是否寫得明確,以及需要的檔案和指令是否真的存在。
這份 skill 也定義了停止條件:工作目錄有未處理的修改、腳本或測試失敗,都要先回報。好的 SOP 除了說明怎麼完成,也要讓執行者知道什麼時候不能繼續。
使用時機寫得太模糊。 「處理專案資料」很難判斷何時適用。用具體任務和使用者會說的話描述。
一份 skill 包含太多不同工作。 如果更新資料、除錯、發版全放在一起,使用條件和步驟容易混淆。先把一件事寫完整,再考慮如何串接。
只存一句 prompt。 「請幫我 review」還不足以構成可重複執行的流程。補上檢查範圍、操作步驟、停止條件與產出。
照搬現成版本,沒有換成自己的環境。 參考別人的結構很有幫助,但路徑、指令和限制必須符合你的專案。
寫完沒試。 實際跑一次,才能知道它是否會被使用、步驟是否可執行,以及能否交出你要的結果。
把下面的骨架存成 SKILL.md.template,用專案裡的一段既有流程填入。
---
name: <以小寫英文和連字號命名>
description: >
<做什麼>。當使用者說「<說法 1>」「<說法 2>」時使用。
<主要步驟與不適用的情況>。
---
# <名稱>
<一句話說明目的>
## 何時用
- <適用的任務>
## 何時不用
- <容易混淆、但不屬於這份流程的任務>
## 步驟
1. <前置檢查與停止條件>
2. <要執行的動作,附上實際路徑或指令來源>
3. <提供哪些差異供使用者檢查>
4. <如何驗證;失敗時如何處理>
5. <交付結果,以及哪些後續動作需要使用者決定>
## 常見錯誤
- <容易漏掉的步驟或不該做的動作,以及原因>
## 產出
<變更清單、驗證結果或其他可檢查的成果>
挑選第一個題目的標準很簡單:你有沒有一段「每次做,都怕自己漏一步」的流程?把那一步寫進去,就是一個有用的開始。